package com.cj.mobile.iabp.mvp.presenter;

import static com.cj.mobile.iabp.BuildConfig.IS_DEBUG_DATA;

import android.os.Bundle;
import android.text.TextUtils;

import com.cj.mobile.iabp.app.config.CommonRetryWithDelay;
import com.cj.mobile.iabp.app.global.Constant;
import com.cj.mobile.iabp.app.utils.CommonUtils;
import com.cj.mobile.iabp.app.utils.CompressImage;
import com.cj.mobile.iabp.app.utils.RxUtils;
import com.cj.mobile.iabp.mvp.contract.AddRoundsInfoContract;
import com.cj.mobile.iabp.mvp.model.entity.DictInfo;
import com.cj.mobile.iabp.mvp.model.entity.RoundsInfo;
import com.jess.arms.di.scope.ActivityScope;
import com.jess.arms.mvp.BasePresenter;
import com.jess.arms.utils.RxLifecycleUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;

/**
 * ================================================
 * Description:
 * <p>
 * Created by MVPArmsTemplate on 2025/09/28 15:20
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms/wiki">See me</a>
 * <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
 * ================================================
 */
@ActivityScope
public class AddRoundsInfoPresenter extends BasePresenter<AddRoundsInfoContract.Model, AddRoundsInfoContract.View> {
    @Inject
    RxErrorHandler mErrorHandler;

    // 查房id
    private String roundsId;
    // 患者id
    private String id;
    // 患者登记号
    private String code;
    // 患者姓名
    private String name;
    // 所在病房
    private String area;
    // 所在床号
    private String bedNo;
    // 查房信息
    private RoundsInfo info;
    // 是否修改
    private boolean isModify;
    // 手术信息中的机器代码
    private String machineCode;

    // 拍照图片(本地)
    private ArrayList<String> takePicturesImgs;
    private ArrayList<String> updateImgs;

    @Inject
    public AddRoundsInfoPresenter(AddRoundsInfoContract.Model model, AddRoundsInfoContract.View rootView) {
        super(model, rootView);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mErrorHandler = null;
        this.takePicturesImgs = null;
        this.updateImgs = null;
    }


    public void getBundleValues(Bundle bundle) {
        if (bundle != null) {
            id = bundle.getString("id");
            code = bundle.getString("code");
            name = bundle.getString("name");
            area = bundle.getString("area");
            bedNo = bundle.getString("bedNo");

            machineCode = bundle.getString("machineCode");

            info = bundle.getParcelable("info");
            if (info != null)
                roundsId = info.getId();
        }

        isModify = info != null;
    }

    public void initData(Bundle bundle) {
        getBundleValues(bundle);

        takePicturesImgs = new ArrayList<>();
        updateImgs = new ArrayList<>();
        // 显示登记号和患者姓名
        mRootView.showSurgeryInfo(code, name, area, bedNo, machineCode, info);

        getDoctor();
    }


    /**
     * 获取医生字典
     */
    public void getDoctor() {
        if (IS_DEBUG_DATA) {
            List<DictInfo> list = new ArrayList<>();
            list.add(new DictInfo(302, "", 0, "3", "王敏", "王敏", "", "", "2025-06-08 09:22:39", "pc", "", "", "1", "0"));
            list.add(new DictInfo(303, "", 0, "3", "高峻迪", "高峻迪", "", "", "2025-06-08 09:22:39", "pc", "", "", "1", "0"));
            list.add(new DictInfo(304, "", 0, "3", "杨颂", "杨颂", "", "", "2025-06-08 09:22:39", "pc", "", "", "1", "0"));
            list.add(new DictInfo(266, "安装人员", 0, "3", "侯晓彤", "侯晓彤", "1", "", "2025-06-08 09:22:39", "pc", "", "", "1", "0"));
            list.add(new DictInfo(267, "安装人员", 0, "3", "黑飞龙", "黑飞龙", "2", "", "2025-06-08 09:22:39", "pc", "", "", "1", "0"));
            list.add(new DictInfo(268, "安装人员", 0, "3", "杨璟", "杨璟", "3", "", "2025-06-08 09:22:39", "pc", "", "", "1", "0"));
            list.add(new DictInfo(269, "安装人员", 0, "3", "郝星", "郝星", "4", "", "2025-06-08 09:22:39", "pc", "", "", "1", "0"));

            mRootView.loadWardRounds(list);
        } else {
            mModel.getDictList("3")
                    .compose(RxUtils.applySchedulers(mRootView)) // 使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
                    .subscribe(new ErrorHandleSubscriber<List<DictInfo>>(mErrorHandler) {

                        @Override
                        public void onNext(List<DictInfo> list) {
                            if (CommonUtils.isNotEmpty(list)) {
                                mRootView.loadWardRounds(list);
                            }

                        }
                    });
        }

    }


    /**
     * 提交事件
     *
     * @param doctorId   医生id
     * @param doctorName 医生姓名
     * @param place1     胸片位置
     * @param place2     胸片位置调整
     * @param roundTime  查房时间
     * @param fbType     反搏效果
     * @param gssType    肝素水量
     * @param yali       压力带压力
     * @param haiqi      氦气量
     * @param lessL      下肢缺血 - 安装侧
     * @param lessR      下肢缺血 - 对侧
     * @param ecmo       ECMO时机
     * @param mashine    机器代码
     * @param special    特殊情况详述
     * @param checkTime  检验日期
     * @param ast        AST
     * @param alt        ALT
     * @param cr         肌酐Cr
     * @param egfr       eGFR
     * @param myo        肌红蛋白
     * @param clac       乳酸cLac
     * @param ga         肌钙蛋白
     * @param leftSize   左室舒张末期内径
     * @param leftScore  左室射血分数
     */
    public void btnSubmit(String pre, String doctorId, String doctorName, String place1, String place2,
                          String roundTime, String fbType, String gssType, String yali, String haiqi,
                          List<String> lessL, List<String> lessR, String ecmo, String mashine, String special,
                          String checkTime, String ast, String alt, String cr, String egfr, String myo, String clac,
                          String ga, String leftSize, String leftScore, List<String> files) {
        if (IS_DEBUG_DATA) {
            mRootView.showMessage("信息维护成功！");
        } else {

            if (isModify) {
                // 修改查房信息

                // “mImgs”中存在混合图(既有网上的，又有拍照的)，特殊处理：将“mImgs”逐条过滤成两个变量。
                // 然后 “拍照的” 单独上传，上传成功后做一次合并。然后再提交数据。
                filterImg(files);

                if (CommonUtils.isNotEmpty(takePicturesImgs)) {
                    compressImage(takePicturesImgs, path -> mModel.upload(path)
                            .subscribeOn(Schedulers.io())
                            .retryWhen(new CommonRetryWithDelay(2, 2))    // 遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
                            .doOnSubscribe(disposable -> {
                                mRootView.showLoadingSubmit();
                            })
                            .subscribeOn(AndroidSchedulers.mainThread())
                            .observeOn(AndroidSchedulers.mainThread())
                            .doFinally(() -> {
                            }).compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                            .flatMap((Function<List<String>, ObservableSource<Integer>>) infoResponse -> {
                                // 合并图片
                                infoResponse.addAll(updateImgs);
                                // 更新接口
                                return mModel.updateRounds(pre, roundsId, id, doctorId, "", name,
                                                bedNo, area, doctorName, place1, place2,
                                                roundTime, fbType, gssType, yali, haiqi,
                                                lessL, lessR, ecmo, mashine, special,
                                                checkTime, ast, alt, cr, egfr, myo, clac,
                                                ga, leftSize, leftScore, infoResponse)
                                        .subscribeOn(Schedulers.io())
                                        .retryWhen(new CommonRetryWithDelay(2, 2))    // 遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
                                        .doOnSubscribe(disposable -> {
                                        })
                                        .subscribeOn(AndroidSchedulers.mainThread())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .doFinally(() -> {
                                            mRootView.hideLoadingSubmit();
                                        }).compose(RxLifecycleUtils.bindToLifecycle(mRootView));                            // 切换线程

                            })
                            .subscribe(new ErrorHandleSubscriber<Integer>(mErrorHandler) {

                                @Override
                                public void onNext(Integer commonResponse) {
                                    mRootView.showMessage("修改成功！");
                                    mRootView.killMyself();
                                }
                            }));

                } else {
                    // 基本信息
                    mModel.updateRounds(pre, roundsId, id, doctorId, "", name,
                                    bedNo, area, doctorName, place1, place2,
                                    roundTime, fbType, gssType, yali, haiqi,
                                    lessL, lessR, ecmo, mashine, special,
                                    checkTime, ast, alt, cr, egfr, myo, clac,
                                    ga, leftSize, leftScore, null)
                            .subscribeOn(Schedulers.io())
                            .retryWhen(new CommonRetryWithDelay(2, 2))    // 遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
                            .doOnSubscribe(disposable -> {
                                mRootView.showLoadingSubmit();
                            })
                            .subscribeOn(AndroidSchedulers.mainThread())
                            .observeOn(AndroidSchedulers.mainThread())
                            .doFinally(() -> {
                                mRootView.hideLoadingSubmit();
                            }).compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                            .subscribe(new ErrorHandleSubscriber<Integer>(mErrorHandler) {

                                @Override
                                public void onNext(Integer commonResponse) {
                                    mRootView.showMessage("修改成功！");
                                    mRootView.killMyself();
                                }
                            });
                }
            } else {
                // 新增查房信息
                if (CommonUtils.isNotEmpty(files)) {
                    compressImage(files, path -> mModel.upload(path)
                            .subscribeOn(Schedulers.io())
                            .retryWhen(new CommonRetryWithDelay(2, 2))    // 遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
                            .doOnSubscribe(disposable -> {
                                mRootView.showLoadingSubmit();
                            })
                            .subscribeOn(AndroidSchedulers.mainThread())
                            .observeOn(AndroidSchedulers.mainThread())
                            .doFinally(() -> {
                            }).compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                            .flatMap((Function<List<String>, ObservableSource<Integer>>) infoResponse -> {

                                // 更新接口
                                return mModel.addRoundsInfo(pre, id, doctorId, "", name,
                                                bedNo, area, doctorName, place1, place2,
                                                roundTime, fbType, gssType, yali, haiqi,
                                                lessL, lessR, ecmo, mashine, special,
                                                checkTime, ast, alt, cr, egfr, myo, clac,
                                                ga, leftSize, leftScore, infoResponse)
                                        .subscribeOn(Schedulers.io())
                                        .retryWhen(new CommonRetryWithDelay(2, 2))    // 遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
                                        .doOnSubscribe(disposable -> {
                                        })
                                        .subscribeOn(AndroidSchedulers.mainThread())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .doFinally(() -> {
                                            mRootView.hideLoadingSubmit();
                                        }).compose(RxLifecycleUtils.bindToLifecycle(mRootView));                            // 切换线程

                            })
                            .subscribe(new ErrorHandleSubscriber<Integer>(mErrorHandler) {

                                @Override
                                public void onNext(Integer commonResponse) {
                                    mRootView.showMessage("保存成功！");
                                    mRootView.killMyself();
                                }
                            }));

                } else {
                    // 基本信息
                    mModel.addRoundsInfo(pre, id, doctorId, "", name,
                                    bedNo, area, doctorName, place1, place2,
                                    roundTime, fbType, gssType, yali, haiqi,
                                    lessL, lessR, ecmo, mashine, special,
                                    checkTime, ast, alt, cr, egfr, myo, clac,
                                    ga, leftSize, leftScore, null)
                            .subscribeOn(Schedulers.io())
                            .retryWhen(new CommonRetryWithDelay(2, 2))    // 遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
                            .doOnSubscribe(disposable -> {
                                mRootView.showLoadingSubmit();
                            })
                            .subscribeOn(AndroidSchedulers.mainThread())
                            .observeOn(AndroidSchedulers.mainThread())
                            .doFinally(() -> {
                                mRootView.hideLoadingSubmit();
                            }).compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                            .subscribe(new ErrorHandleSubscriber<Integer>(mErrorHandler) {

                                @Override
                                public void onNext(Integer commonResponse) {
                                    mRootView.showMessage("保存成功！");
                                    mRootView.killMyself();
                                }
                            });
                }
            }
        }
    }


    /**
     * 压缩图片
     */
    private void compressImage(List<String> mImg, CompressImage callback) {
        // 压缩好的图片
        ArrayList<String> newPath = new ArrayList<>();

        Luban.with(mRootView.getActivity())
                .load(mImg)
                .ignoreBy(500)
                .setTargetDir(Constant.IMAGE_PATH)
                .filter(path1 -> !(TextUtils.isEmpty(path1) || path1.toLowerCase().endsWith(".gif")))
                .setCompressListener(new OnCompressListener() {
                    @Override
                    public void onStart() {
                        // 压缩开始前调用，可以在方法内启动 loading UI
                        mRootView.showLoadingSubmit();
                    }

                    @Override
                    public void onSuccess(File file) {
                        // 压缩成功后调用，返回压缩后的图片文件
                        newPath.add(file.getAbsolutePath());

                        // 全部压缩完后，执行上传
                        if (mImg.size() == newPath.size())
                            if (callback != null) {
                                callback.success(newPath);
                            }

                    }

                    @Override
                    public void onError(Throwable e) {
                        // 当压缩过程出现问题时调用
                        mRootView.showMessage("图片压缩过程出现问题：" + e.getMessage());
                        mRootView.hideLoadingSubmit();
                    }
                }).launch();
    }

    /**
     * 图片过滤
     */
    private void filterImg(List<String> mImgs) {
        takePicturesImgs.clear();
        updateImgs.clear();
        for (String str : mImgs) {
            if (str.contains("http")) {
                // 网络原有的
                updateImgs.add(str);
            } else {
                // 本地的
                takePicturesImgs.add(str);
            }
        }
    }
}